package com.jinzhi.jzweb.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.base.CoreServiceImpl;
import com.jinzhi.common.type.EnumErrorCode;
import com.jinzhi.common.utils.EhCacheUtil;
import com.jinzhi.common.utils.Result;
import com.jinzhi.jzweb.dao.ExaminationPaperComDao;
import com.jinzhi.jzweb.domain.*;
import com.jinzhi.jzweb.pojo.ErrorCodeVo;
import com.jinzhi.jzweb.pojo.moduleConfig.PaperVo;
import com.jinzhi.jzweb.service.*;
import com.jinzhi.jzweb.service.moduleConfig.ExaminationQuestionsComService;
import com.jinzhi.jzweb.utils.EasyPoiUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * 
 * <pre>
 * 考试试卷
 * </pre>
 * <small> 2020-02-24 21:00:12 | lance</small>
 */
@Service
public class ExaminationPaperComServiceImpl extends CoreServiceImpl<ExaminationPaperComDao, ExaminationPaperComDO> implements ExaminationPaperComService {

    @Autowired
    private ExaminationQuestionsComService examinationQuestionsComService;

    @Autowired
    private ExaminationBatchComService examinationBatchComService;

    @Autowired
    private CertificationBatchService certificationBatchService;

    @Autowired
    private TestPaperTemplateService testPaperTemplateService;

    @Autowired
    private TemplateDetailsService templateDetailsService;

    @Override
    public List<String> selNumbers(Map map){
        return this.baseMapper.selNumbers(map);
    }

    @Override
    public Result<?> importExcel(MultipartFile file, String cprofileId, Long userId, String paperName,Integer type) {
        //查询考试批次信息
        ExaminationBatchComDO examinationBatchDO = examinationBatchComService.selectById(cprofileId);
        if (examinationBatchDO == null) {
            return Result.fail("对应的考试批次信息有误，请检查或重试！");
        } else {
            if (examinationBatchDO.getState().equals(0) || examinationBatchDO.getState().equals(2)) {
                return Result.fail("该考试批次审核还未通过，请先审核！");
            } //查询认证批次信息
            CertificationBatchDO certificationBatchDO = certificationBatchService.selectById(examinationBatchDO.getCbatchId());
            if (certificationBatchDO == null) {
                return Result.fail("对应的认证批次信息有误，请检查或重试！");
            }
            //查询试卷模板信息
            TestPaperTemplateDO testPaperTemplateDO = testPaperTemplateService.findOneByKv("news_id", certificationBatchDO.getNewsId());

            if (testPaperTemplateDO == null) {
                return Result.fail("未找到对应的试卷模板，请检查或重试！");
            } else {
                double type4 = 0;
                double type5 = 0;
                double type6 = 0;
                List<TemplateDetailsDO> templateDetailsDOS = templateDetailsService.selectList(new EntityWrapper<TemplateDetailsDO>().eq("tptemplate_id", testPaperTemplateDO.getId()).eq("state", 0));
                if(templateDetailsDOS!=null && !templateDetailsDOS.isEmpty()){
                    for (TemplateDetailsDO templateDetailsDO : templateDetailsDOS) {
                        double score = templateDetailsDO.getScore();
                        if(templateDetailsDO.getType()==4){
                            type4 = score;
                        } else if (templateDetailsDO.getType()==5) {
                            type5 = score;
                        } else if (templateDetailsDO.getType()==6) {
                            type6 = score;
                        }
                    }
                }

                //先判断试卷是否存在，不存在则新建试卷，再将题目保存在试卷下
                Wrapper<ExaminationPaperComDO> eq = new EntityWrapper<ExaminationPaperComDO>().eq("ebatch_id", cprofileId).orderBy("sort", false);
                List<ExaminationPaperComDO> examinationPaperComDOS = this.selectList(eq);
                ExaminationPaperComDO examinationPaperComDO = new ExaminationPaperComDO();
                examinationPaperComDO.setName("第1套");
                examinationPaperComDO.setSort(1);
                if (examinationPaperComDOS != null && !examinationPaperComDOS.isEmpty()) {
                    if (null == examinationPaperComDOS.get(0).getSort()) {
                        examinationPaperComDO.setSort(1);
                    } else {
                        examinationPaperComDO.setSort(examinationPaperComDOS.get(0).getSort() + 1);
                    }
                    //查询竞赛名称
                    examinationPaperComDO.setName("第" + examinationPaperComDO.getSort() + "套");
                }
                examinationPaperComDO.setEbatchId(Long.valueOf(cprofileId));
                examinationPaperComDO.setTptemplateId(testPaperTemplateDO.getId());
                examinationPaperComDO.setState(0);
                examinationPaperComDO.setDuration("60");//.先默认60分钟
                examinationPaperComDO.setCreaterId(userId);
                examinationPaperComDO.setCreaterDate(new Date());
                examinationPaperComDO.setEbatchId(Long.valueOf(cprofileId));
                examinationPaperComDO.setType(type);
                this.insert(examinationPaperComDO);

                //第一步--判断文件格式
                if (!"application/vnd.ms-excel".equals(file.getContentType())) {
                    return Result.fail("文件格式错误，请选择.xls文件");
                }
                //第二步--解析文件获得数据
                List<PaperVo> list = EasyPoiUtil.importExcel(file, 1, 1, PaperVo.class);
                if (list.size() == 0) {
                    return Result.fail("Excel数据为空，请完善");
                }
                //---------------------------------验证数据并导入-----------------------------------------
                //数据该表第三行，第一行标题，第二行表头
                int startRow = 3;
                int cout = 1;//错误信息计数
                List<ExaminationQuestionsComDO> bankDOList = new ArrayList<>();
                List<ErrorCodeVo> list1 = new ArrayList<>();
                for (int i = 0; i < list.size(); i++) {
                    StringBuilder sb = new StringBuilder();
                    //第一步验证是否存在空值
                    if (StringUtils.isBlank(list.get(i).getTopicTypes())) {
                        sb.append("第" + (i + startRow) + "行题目类型未填写，请完善！" + ";");
                    } else {
                        if (StringUtils.isBlank(list.get(i).getTopicContent())) {
                            sb.append("第" + (i + startRow) + "行题目内容未填写，请完善！" + ";");
                        } else {
                            //第四步排重验证（自身比较）
                            for (int j = 0; j < list.size(); j++) {
                                if (i != j) {
                                    if (list.get(i).getTopicContent().trim().equals(list.get(j).getTopicContent().trim())) {
                                        sb.append("第" + (i + startRow) + "行跟第" + (j + startRow) + "行题目内容重复，重复值：" + list.get(i).getTopicContent().trim() + ";");
                                    }
                                }
                            }
                            /**
                             * 单项选择题 30小题 每小题0.3分，共9分
                             * 多项选择题 10小题 每小题0.8分，共8分
                             * 判断题 10小题 每小题0.3分 共3分
                             */
                            double score = 0;
                            Integer types = 99;
                            //题目类型（0单选，1多选，2判断，3实操）
                            if (list.get(i).getTopicTypes().equals("单选")) {
                                types = 0;
                                score = type4;
                                if (StringUtils.isBlank(list.get(i).getOptionsA()) || StringUtils.isBlank(list.get(i).getOptionsB()) || StringUtils.isBlank(list.get(i).getOptionsC()) || StringUtils.isBlank(list.get(i).getOptionsD())) {
                                    sb.append("第" + (i + startRow) + "行选项未填写完整，请按照示例填写！" + ";");
                                }
                            } else if (list.get(i).getTopicTypes().equals("多选")) {
                                types = 1;
                                score = type5;
                                if (StringUtils.isBlank(list.get(i).getOptionsA()) || StringUtils.isBlank(list.get(i).getOptionsB()) || StringUtils.isBlank(list.get(i).getOptionsC()) || StringUtils.isBlank(list.get(i).getOptionsD())) {
                                    sb.append("第" + (i + startRow) + "行选项未填写完整，请按照示例填写！" + ";");
                                }
                            } else if (list.get(i).getTopicTypes().equals("判断")) {
                                types = 2;
                                score = type6;
                                if (StringUtils.isBlank(list.get(i).getOptionsA()) || StringUtils.isBlank(list.get(i).getOptionsB())) {
                                    sb.append("第" + (i + startRow) + "行选项未填写完整，请按照示例填写！" + ";");
                                }
                            } else if (list.get(i).getTopicTypes().equals("实操")) {
                                types = 3;
                            } else if (list.get(i).getTopicTypes().equals("制定照护计划")) {
                                types = 4;
                            } else {
                                sb.append("第" + (i + startRow) + "行题目类型填写错误，请按照示例填写" + ";");
                            }

                            if (types != 99) {
                                //第六步排重验证（和数据库比较），根据题目内容、试卷id、题库类型、state 比较
//                        Wrapper<ExaminationQuestionsComDO> wrapper = new EntityWrapper<ExaminationQuestionsComDO>().eq("state", 0).eq("type", type).eq("introduce", list.get(i).getTopicContent());
//                        List<ExaminationQuestionsComDO> examinationQuestionsComDOS = examinationQuestionsComService.selectList(wrapper);
//                        if (examinationQuestionsComDOS != null && !examinationQuestionsComDOS.isEmpty()) {
//                            sb.append("第" + (i + startRow) + "行题目已存在，请检查！" + ";");}
                                ExaminationQuestionsComDO questionsComDO = new ExaminationQuestionsComDO();
                                questionsComDO.setType(types);
                                questionsComDO.setState(0);
                                questionsComDO.setIntroduce(list.get(i).getTopicContent());
                                questionsComDO.setAnswers(list.get(i).getRightKey());
                                questionsComDO.setScore(score);
                                questionsComDO.setEpaperId(examinationPaperComDO.getId());//试卷id
                                String options = "";
                                if (StringUtils.isNotBlank(list.get(i).getOptionsA())) {
                                    options = "A、" + list.get(i).getOptionsA();
                                }
                                if (StringUtils.isNotBlank(list.get(i).getOptionsB())) {
                                    options = options + ";;B、" + list.get(i).getOptionsB();
                                }
                                if (StringUtils.isNotBlank(list.get(i).getOptionsC())) {
                                    options = options + ";;C、" + list.get(i).getOptionsC();
                                }
                                if (StringUtils.isNotBlank(list.get(i).getOptionsD())) {
                                    options = options + ";;D、" + list.get(i).getOptionsD();
                                }
                                if (StringUtils.isNotBlank(list.get(i).getOptionsE())) {
                                    options = options + ";;E、" + list.get(i).getOptionsE();
                                }
                                if (StringUtils.isNotBlank(list.get(i).getOptionsF())) {
                                    options = options + ";;F、" + list.get(i).getOptionsF();
                                }
                                questionsComDO.setOptions(options);
                                bankDOList.add(questionsComDO);
                            }
                        }
                    }
                    if (sb.length() > 0) {
                        ErrorCodeVo errorCodeVo = new ErrorCodeVo();
                        errorCodeVo.setSeq(cout);
                        cout += 1;
                        errorCodeVo.setErrorCode(sb.toString());
                        list1.add(errorCodeVo);

                        this.deleteById(examinationPaperComDO);
                    }

                }

                if (list1.size() == 0) {
                    boolean c = examinationQuestionsComService.insertBatch(bankDOList, bankDOList.size());
                    if (c) {
                        return Result.ok(examinationPaperComDO.getId());
                    } else {
                        return Result.fail("题目信息导入错误，请稍后重试或联系管理员");
                    }
                } else {
                    JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list1));
                    //将list1存到缓存中
                    EhCacheUtil.put("paper" + userId, jsonArray);
                    return Result.build(EnumErrorCode.FileImportError.getCode(), EnumErrorCode.FileImportError.getMsg());
                }
            }
        }
    }


    /**
     * 查询试题祥请或列表
     * @param examinationPaperComDTO
     * @return
     */
    @Override
    public Result<?> queryQuestionsComList(ExaminationPaperComDO examinationPaperComDTO) {
        Page<ExaminationQuestionsComDO> page = new Page<>(
                Optional.ofNullable(examinationPaperComDTO.getPageNumber()).orElse(1),
                Optional.ofNullable(examinationPaperComDTO.getPageSize()).orElse(10));
        EntityWrapper<ExaminationQuestionsComDO> wrapper = new EntityWrapper<>();
        if(null != examinationPaperComDTO.getId()){
            wrapper.eq("epaper_id",examinationPaperComDTO.getId());
        }
        if(null != examinationPaperComDTO.getQuestionsComId()){
            wrapper.eq("id",examinationPaperComDTO.getQuestionsComId());
        }
        wrapper.eq("state",0);
        Page<ExaminationQuestionsComDO> pageList = examinationQuestionsComService.selectPage(page,wrapper);
        return Result.ok(pageList);
    }

    @Override
    public Result<?> questionList(ExaminationPaperComDO examinationPaperComDTO) {
        if(null==examinationPaperComDTO.getId()){
            //默认定义一个id
            examinationPaperComDTO.setId(1111111111111111111L);
        }
        Page<ExaminationQuestionsComDO> page = new Page<>(
                Optional.ofNullable(examinationPaperComDTO.getPageNumber()).orElse(1),
                Optional.ofNullable(examinationPaperComDTO.getPageSize()).orElse(10));
        EntityWrapper<ExaminationQuestionsComDO> wrapper = new EntityWrapper<>();
        wrapper.eq("epaper_id",examinationPaperComDTO.getId());
        if(null != examinationPaperComDTO.getQuestionsComId()){
            wrapper.eq("id",examinationPaperComDTO.getQuestionsComId());
        }
        wrapper.eq("state",0);
        Page<ExaminationQuestionsComDO> pageList = examinationQuestionsComService.selectPage(page,wrapper);
        return Result.ok(pageList);
    }

    /**
     * 指定试卷
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Result<?> specifyPaper(Long id) {
        //将当前试卷设置为考试试卷，将之前的指定的试卷清除
        ExaminationPaperComDO examinationPaperComDO = this.selectById(id);
        ExaminationPaperComDO examinationPaperComDO1 = new ExaminationPaperComDO();
        examinationPaperComDO1.setState(1);
        this.update(examinationPaperComDO1,new EntityWrapper<ExaminationPaperComDO>().eq("ebatch_id",examinationPaperComDO.getEbatchId()).eq("state",99));

        examinationPaperComDO.setState(99);
        this.updateById(examinationPaperComDO);
        return Result.ok();
    }


}
